package com.lw.smartdevice.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lw.smartdevice.cache.CategoryCache;
import com.lw.smartdevice.enums.CheckType;
import com.lw.smartdevice.events.CategoryCacheChangeEvent;
import com.lw.smartdevice.exceptions.DeleteMyBaseException;
import com.lw.smartdevice.exceptions.MyBaseException;
import com.lw.smartdevice.exceptions.MyErrorCode;
import com.lw.smartdevice.exceptions.UpdateMyBaseException;
import com.lw.smartdevice.mapper.SysCategoryMapper;
import com.lw.smartdevice.pojo.SysCategory;
import com.lw.smartdevice.pojo.SysUserInfo;
import com.lw.smartdevice.service.SysCategoryService;
import com.lw.smartdevice.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @version 1.0
 * @description:
 * @date 2022/3/20 19:21
 */
@Service
@Transactional
public class SysCategoryImpl implements SysCategoryService {

    private ApplicationContext applicationContext;

    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    private CategoryCache categoryCache;

    @Autowired
    public void setCategoryCache(CategoryCache categoryCache) {
        this.categoryCache = categoryCache;
    }

    private SysCategoryMapper sysCategoryMapper;

    @Autowired
    public void setSysCategoryMapper(SysCategoryMapper sysCategoryMapper) {
        this.sysCategoryMapper = sysCategoryMapper;
    }

    @Override
    public void addSysCategory(SysCategory sysCategory) {
        //检查数据是不是传递了
        Assert.isTrue(!sysCategory.isEmpty(CheckType.ADD),()->{
            throw new MyBaseException("分类名称没有传递", MyErrorCode.DATA_NULL);
        });
        //检查当前是不是登录了用户，登录之后存在session了
        //只需要从session中取(数据放在哪是我们自己决定的)
        SysUserInfo userInfo = SecurityUtils.getLoginUser();
        //我们要求必须登录
        Assert.notNull(userInfo,()->{
            throw new MyBaseException("未登录",MyErrorCode.NOT_LOGIN);
        });
        //补充数据
        sysCategory.setCreateBy(userInfo.getUsername());
        sysCategory.setCreateTime(new Date());
        sysCategoryMapper.addSysCategory(sysCategory);
        applicationContext.publishEvent(new CategoryCacheChangeEvent());
    }

    @Override
    @Transactional(readOnly = true)
    public SysCategory findById(Long id) {
        //id必须大于0
        SysCategory sysCategory = categoryCache.get(id);
        return sysCategory;
    }

    @Override
    public PageInfo<SysCategory> findAll(int pageNum, int pageSize, String categoryName) {

        PageHelper.startPage(pageNum,pageSize);
        //先用条件过滤掉一部分数据，然后剩下的做分页
        List<SysCategory> categoryList = categoryCache.getCategoryListCache();

//        ArrayList<Object> arrayList=new ArrayList<>();
//        for (SysCategory sysCategory : categoryList) {
//            if(sysCategory.getCategoryName().contains(categoryName)){//包含categoryName添加进去
//                arrayList.add(sysCategory);
//            }
//        }

        //拿到所有和关键字匹配的数据
        List<SysCategory> categories = categoryList.stream().filter(sysCategory -> {
            //如果传值了就代表数据包含，如果没有就直接返回true，就是所以数据都要
            return StringUtils.hasText(categoryName) ? sysCategory.getCategoryName().contains(categoryName) : true;
        }).collect(Collectors.toList());

        //这是当前页要的数据
        List<SysCategory> realList = categories.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());

        //将数据放入pageInfo中
        PageInfo<SysCategory> pageInfo = new PageInfo<>(realList);
        pageInfo.setTotal(categories.size());//设置的是符合条件的所有数据
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        return pageInfo;
    }

    @Override
    public int updateCategory(SysCategory category) {
        //先进行校验
        Assert.isTrue(!category.isEmpty(CheckType.UPDATE),()->{
            throw new UpdateMyBaseException("数据为空",MyErrorCode.DATA_NULL);
        });
        //判断登录
        SysUserInfo userInfo = SecurityUtils.getLoginUser();

        Assert.notNull(userInfo,()->{
            throw new UpdateMyBaseException("未登录",MyErrorCode.NOT_LOGIN);
        });
        //设置其他数据
        category.setUpdateTime(new Date());
        category.setUpdateBy(userInfo.getUsername());
        //更新
        int result = sysCategoryMapper.updateCategory(category);
        //发布事件，更新缓存
        applicationContext.publishEvent(new CategoryCacheChangeEvent());
        return result;
    }

    @Override
    public int deleteByIds(List<Long> ids) {

        Assert.notEmpty(ids,()->{
            throw new DeleteMyBaseException("为传递主键",MyErrorCode.DATA_NULL);
        });
        //检查当前是不是登录了用户，登录之后存在session了
        //只需要从session中取(数据放在哪是我们自己决定的)
        SysUserInfo userInfo = SecurityUtils.getLoginUser();
        //我们要求必须登录
        Assert.notNull(userInfo,()->{
            throw new MyBaseException("未登录",MyErrorCode.NOT_LOGIN);
        });
        int count = sysCategoryMapper.deleteByIds(ids);
        return count;
    }


}
